package mobao.baseinfo.user.service.impl;

import mobao.baseinfo.user.repository.SysUserRepository;
import mobao.baseinfo.user.entity.SysUserT;
import mobao.baseinfo.user.service.SysUserSerivce;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service(value = "SysUserSerivce")
public class SysUserServiceImpl implements SysUserSerivce{

    @Autowired
    private SysUserRepository sysUserRepository;

    @Override
    @Transactional
    public SysUserT save(SysUserT t) {
        sysUserRepository.save(t);
        return t;
    }

    @Override
    public Page<SysUserT> findAll(int page,int size) {
        return sysUserRepository.findAll(new PageRequest(page, size));
    }

    @Override
    public SysUserT findById(Integer userId) {
        Optional<SysUserT> tOpt = sysUserRepository.findById(userId);
        if(tOpt.isPresent()){
            return tOpt.get();
        }
        return null;
    }

    @Transactional
    public void deleteById (Integer userId){
        sysUserRepository.deleteById(userId);
    }

    @Override
    @Transactional
    public void update(SysUserT t) throws Exception{
        SysUserT tOne = sysUserRepository.getOne(t.getUserId());
        if(t.getEmail() != null && !"".equals(t.getEmail())){
            tOne.setEmail(t.getEmail());
        }
        if(t.getMobile() != null && !"".equals(t.getMobile())){
            tOne.setMobile(t.getMobile());
        }
        if(t.getStatus() != -1){
            tOne.setStatus(t.getStatus());
        }
        if(t.getPassword() != null && !"".equals(t.getPassword())){
            tOne.setPassword(t.getPassword());
        }
        if(null != t.getSalt() && !"".equals(t.getSalt())) {
            tOne.setSalt(t.getSalt());
        }
    }

    @Override
    public void updateStatus(Integer status,Integer userId) throws Exception{
        sysUserRepository.updateStatus(status,userId);
    }

    @Override
    public void updatePwd(Integer userId,String password,String salt) throws Exception{
        sysUserRepository.updatePwd(userId,password,salt);
    }

    public Page<SysUserT> findByCondition(SysUserT t,int page,int size){
        Page<SysUserT> result = sysUserRepository.findAll(
            new Specification<SysUserT>(){
                @Override
                public Predicate toPredicate(Root<SysUserT> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicates = new ArrayList<>();
                    if(null != t.getUsername() && !"".equals(t.getUsername())) {
                        predicates.add(criteriaBuilder.like(root.get("username"),t.getUsername()+"%"));
                    }
                    if(null != t.getEmail() && !"".equals(t.getEmail())) {
                        predicates.add(criteriaBuilder.like(root.get("email"),t.getEmail()+"%"));
                    }
                    if(null != t.getMobile() && !"".equals(t.getMobile())) {
                        predicates.add(criteriaBuilder.like(root.get("mobile"),t.getMobile()+"%"));
                    }
                    if(-1 != t.getStatus()) {
                        predicates.add(criteriaBuilder.equal(root.get("status"),t.getStatus()));
                    }
                    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                }
            },new PageRequest(page, size)
        );
        return result;
    }

    @Override
    public boolean checkUsername(String username) {
        long count = sysUserRepository.count(
                new Specification<SysUserT>(){
                    @Override
                    public Predicate toPredicate(Root<SysUserT> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        List<Predicate> predicates = new ArrayList<>();
                        if(null != username && !"".equals(username)) {
                            predicates.add(criteriaBuilder.equal(root.get("username"),username));
                        }
                        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                    }
                });
        if(count > 0){
            return true;
        }
        return false;
    }

    @Override
    public long count() {
        return sysUserRepository.count();
    }
    public long countByCondition(SysUserT t){
        long count = sysUserRepository.count(
                new Specification<SysUserT>(){
                    @Override
                    public Predicate toPredicate(Root<SysUserT> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        List<Predicate> predicates = new ArrayList<>();
                        if(null != t.getUsername() && !"".equals(t.getUsername())) {
                            predicates.add(criteriaBuilder.like(root.get("username"),t.getUsername()+"%"));
                        }
                        if(null != t.getEmail() && !"".equals(t.getEmail())) {
                            predicates.add(criteriaBuilder.like(root.get("email"),t.getEmail()+"%"));
                        }
                        if(null != t.getMobile() && !"".equals(t.getMobile())) {
                            predicates.add(criteriaBuilder.like(root.get("mobile"),t.getMobile()+"%"));
                        }
                        if(-1 != t.getStatus()) {
                            predicates.add(criteriaBuilder.equal(root.get("status"),t.getStatus()));
                        }
                        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                    }
                }
        );
        return count;
    }

    @Override
    public SysUserT getByUsername(String username) {
        List<SysUserT> list = sysUserRepository.findAll(
                new Specification<SysUserT>(){
                    @Override
                    public Predicate toPredicate(Root<SysUserT> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        List<Predicate> predicates = new ArrayList<>();
                        if(null != username && !"".equals(username)) {
                            predicates.add(criteriaBuilder.equal(root.get("username"),username));
                        }
                        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                    }
                }
        );
        if(list.size() > 0){
            return list.get(0);
        }
        return null;
    }
}
